#include "modbus_ctr.h"

Modbus_ctr::Modbus_ctr(QObject *parent) : QObject(parent)
{
    modbusDevice = new QModbusRtuSerialMaster();
    connect(modbusDevice,&QModbusRtuSerialMaster::errorOccurred,this,[=]{
        if(modbusDevice->error() == QModbusDevice::ConnectionError)
        {
            modbusDevice->disconnectDevice();serialFlag = true;
        }
    });
    QTimer *time = new QTimer(this);
    time->start(1000);
    connect(time, &QTimer::timeout, this, &Modbus_ctr::on_sysTick);
}

void Modbus_ctr::on_sysTick()
{
    if(serialFlag)
    {
        QStringList temp = refreshSerial();
        if(!temp.empty())
        {
            emit(serialUpdate(temp));
        }
    }
}

void Modbus_ctr::on_SerialConf(LoadConfig *config, QString com)
{
    qDebug() << "连接的串口号是:" << com;
    qDebug() << "波特率:" << config->baud;
    qDebug() << "从机地址:" << config->id;
    id = config->id;
    if(modbusDevice->state() == QModbusDevice::UnconnectedState)
    {
        modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter,com);  //端口号
        modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter,config->baud);      //波特率
        modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter,0);      //校验位
        modbusDevice->setConnectionParameter(QModbusDevice::SerialDataBitsParameter,8);  //数据位
        modbusDevice->setConnectionParameter(QModbusDevice::SerialStopBitsParameter,1);

        modbusDevice->setTimeout(1000);
        modbusDevice->setNumberOfRetries(0);

        if(!modbusDevice->connectDevice())        
            emit(ModbusState(ErrConnect));
        else
        {
            serialFlag = false;
            emit(ModbusState(Connected));
        }
    }
    else
    {
        modbusDevice->disconnectDevice();
        if(modbusDevice->state() != QModbusDevice::UnconnectedState)
        {
            emit(ModbusState(ErrConnect));
            return;
        }
        ModbusData.clear();
        serialFlag = true;
        emit(ModbusState(DisConnect));
    }
}

void Modbus_ctr::on_readModbus(int addr, int number, bool end)
{
    QModbusDataUnit readUnit(QModbusDataUnit::HoldingRegisters, addr, number);
    QModbusReply *reply = modbusDevice->sendReadRequest(readUnit, id);

    connect(reply, &QModbusReply::finished, this,[=]{

            if (reply->error() != QModbusDevice::NoError)
            {
                emit(ModbusState(ErrRead));
                qDebug() << "err" << QString::number(addr,16) << number;
                ModbusData.clear();
                reply->deleteLater();
                return;
            }
            else
            {
                emit(ModbusState(_MB_OK));
                const QModbusDataUnit unit = reply->result();
                ModbusData.append(unit.values());
                if(end)
                {
//                    qDebug() << ModbusData << ModbusData.size();
                    emit(ModbusDataConver(ModbusData));
//                    qDebug() << "data clear";
                    ModbusData.clear();
                }
//                qDebug() << unit.values();
            }

    });
}

void Modbus_ctr::on_WriteModbus(uint16_t addr, uint16_t val)
{
    QModbusDataUnit writeUnit(QModbusDataUnit::HoldingRegisters, addr, id);
    writeUnit.setValue(0, val);
    modbusDevice->sendWriteRequest(writeUnit, id);
}

QStringList Modbus_ctr::refreshSerial()
{
    Portinfo.clear();
    newListCount = 0;
    foreach(const QSerialPortInfo &SerialInfo,QSerialPortInfo::availablePorts())
    {
        Portinfo += (SerialInfo.portName() +"  "+ SerialInfo.description());
        newListCount++;
    }
    if(newListCount != oldLisrCount)
    {
        oldLisrCount = newListCount;
        return Portinfo;
    }
        Portinfo.clear();

    return Portinfo;
}
